 #pragma once

#include "INetworkChannel.h"
#include "TcpChannel.h"
#include "KcpChannel.h"
#include "TimerManager.h"
#include <memory>
#include <queue>
#include <mutex>
#include <thread>
#include <asio.hpp>

namespace SeanNetwork {

// 网络管理器配置
struct NetworkConfig {
    // 通道切换配置
    uint32_t KcpMaxPacketLoss;      // KCP最大允许连续丢包次数，超过切换到TCP
    uint32_t KcpMaxLatency;         // KCP最大允许延迟(ms)，超过切换到TCP
    uint32_t ChannelDetectInterval; // 通道状态检测间隔(ms)
    
    // 消息配置
    uint32_t MessageTimeToLive;     // 消息生存时间(ms)
    
    // KCP配置
    bool KcpNodelay;                // 是否启用无延迟模式
    int KcpInterval;                // 内部更新间隔(ms)
    int KcpResend;                  // 快速重传触发次数
    bool KcpNoCongestion;           // 是否关闭流控
    int KcpSndWnd;                  // 发送窗口大小
    int KcpRcvWnd;                  // 接收窗口大小
    int KcpMtu;                     // 最大传输单元
    
    // TCP配置
    uint32_t TcpKeepAliveInterval;  // TCP心跳间隔(ms)
    
    // 线程配置
    uint32_t WorkerThreadCount;     // 工作线程数
    
    NetworkConfig()
        : KcpMaxPacketLoss(3),
          KcpMaxLatency(500),
          ChannelDetectInterval(1000),
          MessageTimeToLive(5000),
          KcpNodelay(true),
          KcpInterval(10),
          KcpResend(2),
          KcpNoCongestion(true),
          KcpSndWnd(128),
          KcpRcvWnd(128),
          KcpMtu(1400),
          TcpKeepAliveInterval(15000),
          WorkerThreadCount(2) {
    }
};

// 网络管理器，管理KCP和TCP双通道
class NetworkManager {
public:
    NetworkManager();
    ~NetworkManager();
    
    // 初始化网络管理器
    bool Initialize(const NetworkConfig& config = NetworkConfig());
    
    // 连接到远程主机
    bool Connect(const std::string& host, uint16_t port);
    
    // 断开连接
    void Disconnect();
    
    // 发送消息
    bool SendMsg(std::shared_ptr<NetworkMessage> message);
    
    // 设置消息接收回调
    void SetMessageCallback(MessageReceiveCallback callback);
    
    // 设置连接状态回调
    void SetConnectionCallback(ConnectionStateCallback callback);
    
    // 获取当前连接状态
    ConnectionState GetConnectionState() const;
    
    // 获取当前通道类型
    ChannelType GetCurrentChannelType() const;
    
    // 获取当前网络统计信息
    NetworkStats GetNetworkStats();
    
    // 手动切换通道
    bool SwitchChannel(ChannelType channelType);
    
    // 启动网络管理器
    bool Start();
    
    // 停止网络管理器
    void Stop();
    
private:
    NetworkConfig m_Config;
    
    asio::io_context m_IoContext;
    std::unique_ptr<asio::io_context::work> m_Work;
    std::vector<std::thread> m_WorkerThreads;
    
    std::unique_ptr<TcpChannel> m_TcpChannel;
    std::unique_ptr<KcpChannel> m_KcpChannel;
    
    ChannelType m_CurrentChannel;
    std::atomic<ConnectionState> m_State;
    
    MessageReceiveCallback m_MessageCallback;
    ConnectionStateCallback m_ConnectionCallback;
    
    std::unique_ptr<TimerManager> m_TimerManager;
    uint32_t m_ChannelDetectTimerId;
    
    std::string m_Host;
    uint16_t m_Port;
    
    std::mutex m_ChannelMutex;
    std::mutex m_ReceiveQueueMutex;
    
    std::queue<std::shared_ptr<NetworkMessage>> m_ReceiveQueue;
    
    uint32_t m_KcpConsecutivePacketLoss;
    
    // 获取当前活动通道
    INetworkChannel* GetActiveChannel();
    const INetworkChannel* GetActiveChannel() const;
    
    // 获取备用通道
    INetworkChannel* GetBackupChannel();
    
    // 处理消息接收
    void HandleMessageReceived(std::shared_ptr<NetworkMessage> message, ChannelType sourceChannel);
    
    // 处理连接状态变更
    void HandleConnectionStateChanged(ConnectionState state, const std::string& reason, ChannelType channel);
    
    // 通道状态检测
    void DetectChannelStatus();
    
    /* 功能：处理通道切换判断逻辑
       参数：forceSwitch-是否强制切换通道
       返回：是否执行了通道切换 */
    bool HandleChannelSwitch(bool forceSwitch = false);
    
    // 更新连接状态
    void UpdateConnectionState(ConnectionState newState, const std::string& reason = "");
    
    // 初始化通道
    bool InitializeChannels();
    
    // 启动工作线程
    void StartWorkerThreads();
    
    // 停止工作线程
    void StopWorkerThreads();
};

} // namespace SeanNetwork
